<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>箭头函数中的this(This in arrow functions)</title>
  <!-- 
  在JavaScript中，箭头函数（Arrow Functions）与传统函数在处理this关键字时有显著的不同。
  一、this的定义
  - 在JavaScript中，this关键字指向当前执行上下文的对象。它的值取决于函数的调用方式。

  二、箭头函数的this特性
  1. 不绑定自己的this：
    - 箭头函数不会创建自己的this上下文。相反，它会从外部上下文中“继承”this的值。这意味着在箭头函数内，this的值与定义该箭头函数时的上下文相同。
  2. 适用于回调函数：
    - 由于箭头函数的this特性，它们特别适合用作回调函数，尤其是在事件处理和异步操作中。

  三、注意事项
  1. 不能用作构造函数：
    - 由于箭头函数不绑定自己的this，它们不能作为构造函数，不能使用new关键字调用。
  2. 没有arguments对象：
    - 箭头函数没有自己的arguments对象，因此在需要访问参数时，使用剩余参数语法（...args）会更合适。
  3. 不适合某些场景：
    - 在需要动态改变this的场景中（如某些对象方法），使用传统函数更为合适。

  总结
  - 在箭头函数中，this的值是从外部上下文中继承的，而不是根据调用方式动态绑定的。
  - 这种特性使得箭头函数在处理回调和事件时非常方便，但在需要动态上下文的情况下，传统函数仍然是更好的选择。
  - 理解箭头函数中的this特性对于编写高效和可维护的JavaScript代码至关重要。
   -->
</head>
<body>

  <script>
    // 1. 箭头函数中, 压根没有this
    const bar = () => {
      console.log("bar:", this);
    }
    bar();
    bar.apply({name: "bar"}, [1, 2, 3]);

    // 2. this的值是继承自外部的
    const obj = {
      name: "obj",
      foo: function () {
        console.log("foo:", this);
        const bar = () => {
          console.log("bar:", this);
        }
        return bar;
      }
    }
    const fn = obj.foo();
    fn.apply("abc", [1, 2, 3]); 

    // 3. 箭头函数不能作为构造函数
    // const Foo = () => {};
    // const f = new Foo(); // 报错: Foo is not a constructor

    // 4. 箭头函数没有arguments对象
    const foo = () => {
      // console.log("foo:", arguments);
    }
    foo(1, 2, 3);

    // 4. 应用
    function request(url, callbackFn) {
      const arr = ["function", "string", "number"];
      callbackFn(arr);
    }

    const obj1 = {
      names: [],
      network: function () {
        // 早期时候
        // var _this = this;
        // request("/indexs", (res) => {
        //   this.names = [].concat(res)
        // })
        // 箭头函数
        request("/indexs", (res) => {
          this.names = [].concat(res)
        })
      }
    }

    obj.network();
    console.log(obj1);
    
  </script>
  
</body>
</html>